#include "PreCompile.hpp"
#include "OutStreamTests.hpp"

namespace BuildNG
{
  class TestBuffer
  {
  public:
    TestBuffer(int size)
    {
      this->size = size;

      data = new short[size];

      for(int i = 0;i < size;i++)
        data[i] = (short)i;
    }

    ~TestBuffer()
    {
      delete [] data;
    }

    short *data;
    int size;
  };

  void OutStreamTests::test_write_buffer()
  {
    {
      TestBuffer buffer(4);
      MemoryOutStream stream;
      stream.write_buffer(buffer.data,buffer.size * sizeof(short));

      assert(stream.get_buffer_size() == buffer.size * sizeof(short));
      assert(memcmp(stream.get_buffer(),buffer.data,buffer.size * sizeof(short)) == 0);
    }

    {
      TestBuffer buffer(OutStream::BUFFER_SIZE / sizeof(short));
      MemoryOutStream stream;
      stream.write_buffer(buffer.data,buffer.size * sizeof(short));

      assert(stream.get_buffer_size() == buffer.size * sizeof(short));
      assert(memcmp(stream.get_buffer(),buffer.data,buffer.size * sizeof(short)) == 0);
    }

    {
      TestBuffer buffer(OutStream::BUFFER_SIZE / sizeof(short));
      MemoryOutStream stream;
      stream.write_buffer(buffer.data,buffer.size / 2 * sizeof(short));
      stream.write_buffer(buffer.data + buffer.size / sizeof(short),buffer.size / 2 * sizeof(short));

      assert(stream.get_buffer_size() == buffer.size * sizeof(short));
      assert(memcmp(stream.get_buffer(),buffer.data,buffer.size * sizeof(short)) == 0);
    }

    {
      TestBuffer buffer((OutStream::BUFFER_SIZE + 2) / sizeof(short));
      MemoryOutStream stream;
      stream.write_buffer(buffer.data,sizeof(short));
      stream.write_buffer(buffer.data + 1,(buffer.size - 2)* sizeof(short));
      stream.write_buffer(buffer.data + buffer.size - 1,sizeof(short));

      assert(stream.get_buffer_size() == buffer.size * sizeof(short));
      assert(memcmp(stream.get_buffer(),buffer.data,buffer.size * sizeof(short)) == 0);
    }

    {
      TestBuffer buffer(OutStream::BUFFER_SIZE * 4 / sizeof(short));
      MemoryOutStream stream;
      stream.write_buffer(buffer.data,buffer.size * sizeof(short));

      assert(stream.get_buffer_size() == buffer.size * sizeof(short));
      assert(memcmp(stream.get_buffer(),buffer.data,buffer.size * sizeof(short)) == 0);
    }
  }

  void OutStreamTests::test_write_uint8()
  {
    MemoryOutStream s;
    s.write_uint8(0);
    s.write_uint8(33);
    s.write_uint8(172);
    s.write_uint8(255);
    
    assert(s.get_buffer_size() == 4);
    
    const guint8 *buffer = (const guint8*)s.get_buffer();
    assert(buffer[0] == 0);
    assert(buffer[1] == 33);
    assert(buffer[2] == 172);
    assert(buffer[3] == 255);
  }

  void OutStreamTests::test_write_uint16()
  {
    MemoryOutStream s;
    s.write_uint16(0);
    s.write_uint16(33111);
    s.write_uint16(172);
    s.write_uint16(0xffff);
    
    assert(s.get_buffer_size() == 4 * sizeof(guint16));
    
    const guint16 *buffer = (const guint16*)s.get_buffer();
    assert(buffer[0] == 0);
    assert(buffer[1] == 33111);
    assert(buffer[2] == 172);
    assert(buffer[3] == 0xffff);
  }

  void OutStreamTests::test_write_uint32()
  {
    MemoryOutStream s;
    s.write_uint32(0);
    s.write_uint32(1234567);
    s.write_uint32(172);
    s.write_uint32(0xffffffff);
    
    assert(s.get_buffer_size() == 4 * sizeof(guint32));
    
    const guint32 *buffer = (const guint32*)s.get_buffer();
    assert(buffer[0] == 0);
    assert(buffer[1] == 1234567);
    assert(buffer[2] == 172);
    assert(buffer[3] == 0xffffffff);
  }

  void OutStreamTests::test_write_bool()
  {
    MemoryOutStream s;
    s.write_bool(false);
    s.write_bool(true);

    assert(s.get_buffer_size() == 2);

    const char *buffer = (const char*)s.get_buffer();
    assert(buffer[0] == 0);
    assert(buffer[1] == 1);
  }

  void OutStreamTests::test_write_line()
  {
    MemoryOutStream s;
    s.write_line("This is a line");
    s.write_line("Just as this one");
    s.write_line("But this one is not.\n(It's secretly two lines");
    s.write_line("");
    s.write_line("^^^ Empty line");

    const gchar expected_buffer[] = 
      "This is a line\n"
      "Just as this one\n"
      "But this one is not.\n(It's secretly two lines\n"
      "\n"
      "^^^ Empty line\n";

    int expected_buffer_len = (int)strlen(expected_buffer);
    assert(s.get_buffer_size() == expected_buffer_len);
    assert(memcmp(s.get_buffer(),expected_buffer,expected_buffer_len) == 0);
  }

  void OutStreamTests::test_std_out_stream()
  {
    assert(!"not implemented yet");
  }
}